package net.cassite.daf4j.ds;

import net.cassite.daf4j.QueryParameter;
import net.cassite.daf4j.QueryParameterWithFocus;
import net.cassite.daf4j.UpdateEntry;
import net.cassite.daf4j.Where;

import java.util.List;
import java.util.Map;

/**
 * Where子句的解释器
 *
 * @param <Context>      上下文
 * @param <BasicElement> 基本元素
 */
public interface AroundParser<Context, BasicElement, DS> extends AdvancedParser<Context, BasicElement> {
        /**
         * 执行find功能
         *
         * @param source      数据源
         * @param entityClass 要查找的类型
         * @param pkValue     标识值
         * @param <En>        实体类型
         * @return 查找到则返回该值, 否则返回null
         * @throws Exception 可能的异常
         */
        <En> En find(DS source, Class<En> entityClass, Object pkValue) throws Exception;

        /**
         * 执行list方法时首先调用此方法获取上下文
         *
         * @param source    数据源
         * @param entity    查询来源
         * @param where     查询条件
         * @param parameter 查询参数
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context initiateList(DS source, Object entity, Where where, QueryParameter parameter) throws Exception;

        /**
         * list方法开始解释前调用
         *
         * @param context 上下文
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context beforeParsingList(Context context) throws Exception;

        /**
         * list方法解释完成后,执行开始前调用
         *
         * @param context 上下文
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context afterParsingList(Context context) throws Exception;

        /**
         * list方法执行
         *
         * @param context 上下文
         * @return 取到的List值
         * @throws Exception 可能的异常
         */
        List<?> executeList(Context context) throws Exception;

        /**
         * 执行projection方法时首先调用此方法获取上下文
         *
         * @param source    数据源
         * @param entity    查询来源
         * @param where     查询条件
         * @param parameter 查询参数
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context initiateProjection(DS source, Object entity, Where where, QueryParameterWithFocus parameter) throws Exception;

        /**
         * projection解析开始前调用
         *
         * @param context 上下文
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context beforeParsingProjection(Context context) throws Exception;

        /**
         * projection解析完成后,执行开始前调用
         *
         * @param context 上下文
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context afterParsingProjection(Context context) throws Exception;

        /**
         * 执行projection
         *
         * @param context 上下文
         * @return List[Map]结果
         * @throws Exception 可能的异常
         */
        List<Map<String, Object>> executeProjection(Context context) throws Exception;

        /**
         * 初始化更新操作,生成上下文
         *
         * @param source  数据源
         * @param entity  更新目标
         * @param where   更新条件
         * @param entries 更新内容
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context initiateUpdate(DS source, Object entity, Where where, UpdateEntry[] entries) throws Exception;

        /**
         * update解释开始之前调用
         *
         * @param context 上下文
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context beforeParsingUpdate(Context context) throws Exception;

        /**
         * update解释之后,执行之前调用
         *
         * @param context 上下文
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context afterParsingUpdate(Context context) throws Exception;

        /**
         * 执行update
         *
         * @param context 上下文
         * @throws Exception 可能的异常
         */
        void executeUpdate(Context context) throws Exception;

        /**
         * 初始化remove,生成上下文
         *
         * @param source 数据源
         * @param entity 删除目标
         * @param where  删除条件
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context initiateRemove(DS source, Object entity, Where where) throws Exception;

        /**
         * remove解释之前调用
         *
         * @param context 上下文
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context beforeParsingRemove(Context context) throws Exception;

        /**
         * remove解释之后,执行之前调用
         *
         * @param context 上下文
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context afterParsingRemove(Context context) throws Exception;

        /**
         * 执行remove
         *
         * @param context 上下文
         * @throws Exception 可能的异常
         */
        void executeRemove(Context context) throws Exception;

        /**
         * 执行save
         *
         * @param source   数据源
         * @param entities 要保存的实体
         * @throws Exception 可能的异常
         */
        void save(DS source, Object[] entities) throws Exception;

        /**
         * 解释where之前调用
         *
         * @param context 上下文
         * @param where   条件子句
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context beforeParsingWhere(Context context, Where where) throws Exception;

        /**
         * 解释where之后调用
         *
         * @param context  上下文
         * @param where    条件子句
         * @param whereStr 解释后的where子句
         * @throws Exception 可能的异常
         */
        void afterParsingWhere(Context context, Where where, BasicElement whereStr) throws Exception;

        /**
         * 解释查询参数前调用
         *
         * @param context   上下文
         * @param parameter 查询参数
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context beforeParsingQueryParameter(Context context, QueryParameter parameter) throws Exception;

        /**
         * 解释查询参数后调用
         *
         * @param context 上下文
         * @throws Exception 可能的异常
         */
        void afterParsingQueryParameter(Context context) throws Exception;

        /**
         * 解释取字段时调用
         *
         * @param context 上下文
         * @param qpwf    带取字段的参数
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context beforeParsingFocusPart(Context context, QueryParameterWithFocus qpwf) throws Exception;

        /**
         * 解释取字段后调用
         *
         * @param context 上下文
         * @throws Exception 可能的异常
         */
        void afterParsingFocusPart(Context context) throws Exception;

        /**
         * 解释更新项目前执行
         *
         * @param context 上下文
         * @param entries 更新项目
         * @return 上下文
         * @throws Exception 可能的异常
         */
        Context beforeParsingUpdateEntries(Context context, UpdateEntry[] entries) throws Exception;

        /**
         * 销毁DataSource
         *
         * @param source 数据源
         */
        void destroy(DS source);

        /**
         * 解释更新项目后执行
         *
         * @param context 上下文
         * @throws Exception 可能的异常
         */
        void afterParsingUpdateEntries(Context context) throws Exception;

        void setParserPacket(ParserPacket<Context, BasicElement, DS> packet);
}
